package com.chen10.cattle.ai;

import com.chen10.cattle.ai.model.Position;

public class GobangAI {

    private static final int BOARD_SIZE = 16; // 假设棋盘是15x15
    private static final int EMPTY = 0;
    private static final int BLACK = -1;
    private static final int WHITE = 1;

    // 评分规则（你可以根据实际情况调整）
    private static final int INF = Integer.MAX_VALUE;
    private static final int CONNECT_FIVE = 100000;
    private static final int ACTIVE_FOUR = 10000;
    private static final int BLOCKED_FOUR = 8000;
    private static final int CONNECT_FOUR = 5000;
    private static final int ACTIVE_THREE = 1000;
    private static final int BLOCKED_THREE = 800;
    private static final int CONNECT_THREE = 500;
    private static final int ACTIVE_TWO = 100;
    private static final int BLOCKED_TWO = 50;
    private static final int CONNECT_TWO = 30;
    private static final int MAX_DEPTH = 1; // 设置递归的最大深度

    // 获取最佳决策
    public Position getBestMove(int[][] board) {
        int bestScore = Integer.MIN_VALUE;
        Position bestMove = null;

        // 遍历每个位置，尝试模拟下棋并使用Minimax算法评估
        for (int row = 0; row < BOARD_SIZE; row++) {
            for (int col = 0; col < BOARD_SIZE; col++) {
                if (board[row][col] == 0) { // 找到空位
                    board[row][col] = WHITE; // 假设AI下白棋
                    int score = minimax(board, MAX_DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE, false);
                    board[row][col] = EMPTY; // 回溯
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove = new Position(row, col);
                    }
                }
            }
        }

        return bestMove;
    }

    // Minimax + Alpha-Beta剪枝算法
    private int minimax(int[][] board, int depth, int alpha, int beta, boolean isMaximizingPlayer) {
        if (depth == 0 || gameOver(board)) {
            return evaluateBoard(board); // 基本情况：评估当前棋盘
        }

        if (isMaximizingPlayer) { // AI是最大化玩家（白棋）
            int maxEval = Integer.MIN_VALUE;
            for (int row = 0; row < BOARD_SIZE; row++) {
                for (int col = 0; col < BOARD_SIZE; col++) {
                    if (board[row][col] == EMPTY) { // 找到空位
                        board[row][col] = WHITE; // AI下白棋
                        int eval = minimax(board, depth - 1, alpha, beta, false);
                        board[row][col] = EMPTY; // 回溯
                        maxEval = Math.max(maxEval, eval);
                        alpha = Math.max(alpha, eval);
                        if (beta <= alpha) {
                            break; // 剪枝
                        }
                    }
                }
            }
            return maxEval;
        } else { // 对手是最小化玩家（黑棋）
            int minEval = Integer.MAX_VALUE;
            for (int row = 0; row < BOARD_SIZE; row++) {
                for (int col = 0; col < BOARD_SIZE; col++) {
                    if (board[row][col] == EMPTY) { // 找到空位
                        board[row][col] = BLACK; // 对手下黑棋
                        int eval = minimax(board, depth - 1, alpha, beta, true);
                        board[row][col] = EMPTY; // 回溯
                        minEval = Math.min(minEval, eval);
                        beta = Math.min(beta, eval);
                        if (beta <= alpha) {
                            break; // 剪枝
                        }
                    }
                }
            }
            return minEval;
        }
    }

    // 检查游戏是否结束（这里仅为一个示例，具体逻辑需根据五子棋规则编写）
    private boolean gameOver(int[][] board) {
        // 这里你可以检查是否已经有玩家获胜
        // 暂时返回false作为示例
        return false;
    }

    // 检查一条线是否符合某个棋型
    private int evaluateLine(int[] line, int player) {
        int score = 0;
        int countPlayer = 0;
        int countOpponent = 0;

        for (int i = 0; i < line.length; i++) {
            if (line[i] == player) countPlayer++;
            else if (line[i] == -player) countOpponent++;
        }

        if (countPlayer == 5) score += CONNECT_FIVE;
        else if (countPlayer == 4 && countOpponent == 0) score += ACTIVE_FOUR;
        else if (countPlayer == 4 && countOpponent == 1) score += BLOCKED_FOUR;
        else if (countPlayer == 3 && countOpponent == 0) score += ACTIVE_THREE;
        else if (countPlayer == 3 && countOpponent == 1) score += BLOCKED_THREE;
        else if (countPlayer == 2 && countOpponent == 0) score += ACTIVE_TWO;
        else if (countPlayer == 2 && countOpponent == 1) score += BLOCKED_TWO;

        return score;
    }

    // 评估棋盘
    public int evaluateBoard(int[][] board) {
        int score = 0;

        for (int row = 0; row < BOARD_SIZE; row++) {
            for (int col = 0; col < BOARD_SIZE; col++) {
                if (board[row][col] != EMPTY) {
                    // 对于每个棋子，检查其在四个方向上的棋型
                    int[] directions[] = {
                            new int[9], // 水平
                            new int[9], // 竖直
                            new int[9], // 左上到右下
                            new int[9]  // 左下到右上
                    };

                    // 获取每个方向的棋子阵列
                    for (int dir = 0; dir < 4; dir++) {
                        for (int i = -4; i <= 4; i++) {
                            int newRow = row, newCol = col;

                            switch (dir) {
                                case 0: // 水平
                                    newCol = col + i;
                                    break;
                                case 1: // 竖直
                                    newRow = row + i;
                                    break;
                                case 2: // 左上到右下
                                    newRow = row + i;
                                    newCol = col + i;
                                    break;
                                case 3: // 左下到右上
                                    newRow = row - i;
                                    newCol = col + i;
                                    break;
                            }

                            // 确保新位置在棋盘内
                            if (newRow >= 0 && newRow < BOARD_SIZE && newCol >= 0 && newCol < BOARD_SIZE) {
                                directions[dir][i + 4] = board[newRow][newCol];
                            } else {
                                directions[dir][i + 4] = EMPTY; // 超出边界设为EMPTY
                            }
                        }
                        score += evaluateLine(directions[dir], WHITE); // 评估白棋
                        score -= evaluateLine(directions[dir], BLACK); // 评估黑棋
                    }
                }
            }
        }
        return score;
    }
}
